
#ifndef __TASK_H
#define __TASK_H

#include "includes.h"

// Types
#define tid_t int
#define TID_NONE -1

// Task states
#define ST_RUNNING 0x0
#define ST_RECV    0x1
#define ST_SEND    0x2
#define ST_HALTED  0x3
#define ST_ERROR   0x4
#define ST_SYSTEM  0x5
#define ST_NOTASK  0x6

// System limits
#define STACK_SIZE 0x1000
#define HEAP_SIZE 0x1000
#define MAX_TASKS 10


struct message
{
  tid_t from;
  void *arg;
  struct message *next;
};

// Stores state of each task
struct task_info
{
  void **ex_stack;
  void **op_stack;
  void **heap;
  void **frame;
  void **retval;
  void **ex_stack_limit;
  void **op_stack_limit;
  void **heap_limit;
  void **ex_stack_start;
  void **op_stack_start;
  void **heap_start;
  void **send_to;
  void **send_arg;
  struct message *msg;
  tid_t tid : 32            __attribute__((packed));
  unsigned int numargs : 8  __attribute__((packed));
  unsigned int state : 8    __attribute__((packed));
  unsigned int unused : 16  __attribute__((packed));
};


// Global variables (registers in virtual machine)
extern unsigned int timeout;
extern unsigned int num_tasks;
extern void *frame_ptr;
extern struct task_info *task_ptr;
extern struct task_info task_table[MAX_TASKS];

int
create_task(void *function, void *argument, void *extra);

void
task_cleanup();

void
grow_op_stack();

void
print_stack();

void
print_ex_stack();

void
check_stack_bounds();

void
schedule();

#endif
